//Pull in DMA commands
#include <spu_mfcio.h>
#include <math.h>
#include <stdlib.h>

#define ilspe		6	// ilosc SPE
#define iln			36	// ilosc neuronow
#define dlw			256	// dlugosc wektora neuronu/obrazu

// struktura do komunikacji z PPE
typedef struct {
	float obraz[dlw];
	float neuron[iln/ilspe][dlw];
	float odleglosc[iln/ilspe];
	int padding[2];
} ppe_data;
float suma;
int i,d;
/* wektoryzacja */
vector float * vobraz;
vector float * vneuron;
vector float * vwynik;
float *tmptab;
vector float tmpv;

int main(unsigned long long spe_id, unsigned long long program_data_ea, unsigned 
long long env) {
	ppe_data pd __attribute__((aligned(16)));
	int tag_id = 0;

	// wczytanie danych
	// kopiowanie
	mfc_get(&pd, program_data_ea, sizeof(pd), tag_id, 0, 0);
	// czekanie na zakonczenie
	mfc_write_tag_mask(1<<tag_id);
	mfc_read_tag_status_any();

	/* dynamiczne allokowanie tablicy tymczasowej na wyniki */
        tmptab=(float*)malloc((size_t)dlw*sizeof(float)); 

	vobraz = (vector float *) pd.obraz;
	vwynik = (vector float *) tmptab;
	// obliczenia
	for(i=0;i<iln/ilspe;i++){
		suma=0;
		vneuron = (vector float *) pd.neuron[i];
		for(d=0;d<dlw/4;d++){
			tmpv=spu_sub(vobraz[d],vneuron[d]);
			vwynik[d]=spu_mul(tmpv,tmpv);
			//suma+=pow(pd.obraz[d]-pd.neuron[i][d],2.0f);
		}
		for(d=0;d<dlw;d++){
			suma+=tmptab[d];
		}
		pd.odleglosc[i]=(float)sqrt((double)suma);
	}

	// wyslanie rezultatu
	// kopiowanie
	mfc_put(&pd, program_data_ea, sizeof(ppe_data), tag_id, 0, 0);
	// czekanie na zakonczenie
	mfc_write_tag_mask(1<<tag_id);
	mfc_read_tag_status_any();
	return 0;
}

